<?php

namespace App\Module\Sub;

use App\depository\ManagePlayerDep;
use App\depository\PermissionsDep;
use App\depository\RoleHasPermissionsDep;
use App\depository\RolesDep;
use App\depository\SubRoleHasPermissionsDep;
use App\depository\SubRolesDep;
use App\depository\SubTeamUserDep;
use App\depository\SystemDep;
use App\depository\UserDep;
use App\Enum\CommonEnum;
use App\Enum\RolesEnum;
use App\Enum\UsersEnum;
use App\Mail\SendCode;
use App\Models\TokenModel;
use App\Models\User as UserModel;
use App\Module\BaseModule;
use App\Service\DictService;
use App\depository\UserHasTeamsDep;
use App\Service\CodeService;
use Illuminate\Support\Facades\Mail;
use App\depository\SubPermissionsDep;
use App\depository\TeamsDep;
use App\depository\SubUserHasRolesDep;

class SubUserModule extends BaseModule
{
    public function login($request)
    {
        $param = $request->input();

        $resUser = UserModel::where("name", $param['username'])->where("password", $param['password'])->first();
        if (!$resUser) {
            return self::response([], '用户名或密码错误', 200);
        }

        $token = $resUser->createToken('gonghui_pc_token')->plainTextToken;
        $detail = [
            'id' => $resUser->id
        ];
        return self::response(['token' => $token, 'detail' => $detail]);
    }

    public function list($request)
    {

        $param = $request->input();

        $teamId = $request->headers->get('TeamId');
        $param['per_page'] = $param['per_page'] ?? 10;
        $param['current_page'] = $param['current_page'] ?? 1;

        $subRoleDep = new SubRolesDep();
        $dep = new UserDep();
        $subUserHasRolesDep = new SubUserHasRolesDep();

        $resList = $dep->subUserList($teamId,$param);

        $list = $resList->getCollection()->toBase();
        $data['list'] = $list->map(function ($item) use ($subRoleDep,$subUserHasRolesDep,$teamId) {
            $resRoleId = $subUserHasRolesDep->firstByUserId($teamId,$item->id);
            if(!$resRoleId){
                $role = "";
            }else{
                $resRole = $subRoleDep->firstByRoleId($resRoleId->role_id);
                $role = $resRole ?  $resRole->name : "";
            }
            return [
                "id" => $item->id,
                "username" => $item->name,
                "password" => $item->password,
                "nickname" => $item->nickname,
                "role" => $role ?: CommonEnum::DEFAULT_NULL,
                "role_id" => $resRoleId ? $resRoleId->role_id : "",
                "email" => $item->email,
                "status" => $item->status,
                "status_show" => UsersEnum::$statusArr[$item->status] ?? CommonEnum::DEFAULT_NULL,
                "created_at" => $item->created_at->toDateTimeString()
            ];
        });

        $data['page'] = [
            'per_page' => $param['per_page'],
            'current_page' => $param['current_page'],
            'total_page' => $resList->lastPage(),
            'total' => $resList->total(),
        ];

        return self::response($data);
    }

    public function init($request)
    {

        $dictService = new DictService();
        $teamId = $request->headers->get('TeamId');

        $dictService->setSubRoles($teamId)->setUserStatus();

        $data['dict'] = $dictService->getDict();

        return self::response($data);
    }

    public function add($request)
    {

        $param = $request->input();
        $userDep = new UserDep();

        $resFind = $userDep->firstByUsername($param['username']);
        if ($resFind) {
            return self::response([], "账号已存在，请勿重复添加", 200);
        }

        $data = [
            'username' => $param['username'],
            'integral' => $param['integral'],
            'expire_at' => $param['expire_at'],
        ];

        $userDep->add($data);
        return self::response();
    }

    public function del($request)
    {

        $param = $request->input();
        $teamId = $request->headers->get('TeamId');

        $dep = new SubTeamUserDep();
        $roleDep = new SubUserHasRolesDep();

        $roleDep->delByUserId($teamId,$param['id']);
        $dep->delByUserId($teamId,$param['id']);

        TokenModel::where('tokenable_id',$param['id'])->delete();

        return self::response();
    }

    public function edit($request)
    {
        $param = $request->input();

        $teamId = $request->headers->get('TeamId');

        $userDep = new UserDep();
        $userHasRoleDep = new SubUserHasRolesDep();

        if (empty($param['username']) || empty($param['password']) || empty($param['nickname'])) {
            return self::response([], '必填项不可以为空', 100);
        }

        $resFind = $userDep->firstByUsername($param['username']);
        if ($resFind && $resFind->id !== $param['id']) {
            return self::response([], "账号已被使用，请重新填写", 200);
        }

        $data = [
            'name' => $param['username'],
            'password' => $param['password'],
            'nickname' => $param['nickname'],
//            'role_id' => $param['role_id'],
            'status' => $param['status']
        ];

        $userDep->upd($param['id'], $data);

        $userHasRoleDep->delByUserId($teamId,$param['id']);
        if (!empty($param['role_id'])) {
            $data = [
                'team_id' => $teamId,
                'user_id' => $param['id'],
                'role_id' => $param['role_id']
            ];
            $userHasRoleDep->add($data);
        }
        return self::response();
    }

    public function detail($request)
    {

        $param = $request->input();

        $userDep = new UserDep();
        $resDetail = $userDep->firstById($param['id']);

        $data['detail'] = [
            'id' => $resDetail->id,
            'username' => $resDetail->name,
            'password' => $resDetail->password,
            'email' => $resDetail->email,
            'nickname' => $resDetail->nickname,
        ];

        return self::response($data);

    }

    public function sendCode($request)
    {

        $param = $request->input();

        $codeService = new CodeService($request->session());

        $code = $codeService->setCode();

        try {
            Mail::to($param['email'])->send(new SendCode($code));
        } catch (\Exception $err) {
            return self::response([], '邮件发送失败，请检查邮箱是否正确', 200);
        }

        return self::response();

    }

    public function register($request)
    {

        $param = $request->input();

        $userDep = new UserDep();


        if (empty($param['username'])) {
            return self::response([], '请输入用户名', 100);
        }

        $resUser = $userDep->firstByUsername($param['username']);
        if ($resUser) {
            return self::response([], '用户名已被占用，请重新输入', 100);
        }


        if (empty($param['nickname'])) {
            return self::response([], '请输入昵称', 100);
        }

        if (empty($param['email'])) {
            return self::response([], '请输入邮箱', 100);
        }

        if (empty($param['code'])) {
            return self::response([], '请输入验证码', 100);
        }

        $codeService = new CodeService($request->session());
        $resCheckCode = $codeService->checkCode($param['code']);
        if (!$resCheckCode['success']) {
            return self::response([], $resCheckCode['msg'], 100);
        }

        if (empty($param['password'])) {
            return self::response([], '请输入密码', 100);
        }

        if (empty($param['confirm_password'])) {
            return self::response([], '请输入确认密码', 100);
        }

        if ($param['password'] != $param['confirm_password']) {
            return self::response([], '两次密码输入不一致', 100);
        }

        $roleDep = new RolesDep();
        $resRole = $roleDep->firstByGuardName(RolesEnum::ROLE_CUSTOMER);
        if (!$resRole) {
            return self::response([], '请联系管理员添加默认访客角色', 200);
        }

        $data = [
            'name' => $param['username'],
            'nickname' => $param['nickname'],
            'email' => $param['email'],
            'email_verified_at' => date('Y-m-d H:i:s'),
            'role_id' => $resRole->id,
            'password' => $param['password'],
        ];


        $userDep->add($data);

        return self::response();
    }


    public function changeProfile($request)
    {

        $param = $request->input();

        $userDep = new UserDep();

        $resUser = $userDep->firstById($request->user()->id);

        if (empty($param['nickname'])) {
            return self::response([], '请输入昵称', 100);
        }

        if (empty($param['email'])) {
            return self::response([], '请输入邮箱', 100);
        }


        if ($param['email'] != $resUser->email) {
            if (empty($param['code'])) {
                return self::response([], '请输入邮箱验证码', 100);
            }
            $codeService = new CodeService($request->session());
            $resCheckCode = $codeService->checkCode($param['code']);
            if (!$resCheckCode['success']) {
                return self::response([], $resCheckCode['msg'], 100);
            }
        }

        if (empty($param['password'])) {
            return self::response([], '请输入密码', 100);
        }

        $data = [
            'name' => $param['username'],
            'nickname' => $param['nickname'],
            'email' => $param['email'],
            'email_verified_at' => date('Y-m-d H:i:s'),
            'password' => $param['password'],
        ];

        $userDep->upd($param['id'], $data);

        return self::response();

    }

    public function permissions($request)
    {

        $param = $request->input();
        $user = $request->user();

        $userId = $user->id;
        $teamId = $request->headers->get('TeamId');

        $userDep = new UserDep();
        $resUser = $userDep->firstById($userId);
        $data['user'] = ['name' => $resUser->name,'is_admin' => $user->is_admin];

        $userHasTeamsDep = new UserHasTeamsDep();
        $resUserHasTeams = $userHasTeamsDep->firstByTeamIdUserId($teamId, $userId);
        $subPermissionsDep = new SubPermissionsDep();
        $resAllPermission = $subPermissionsDep->normalMenu()->map(function ($item) {
            return $item->guard_name;
        });

        $teamsDep = new TeamsDep();
        $resTeam = $teamsDep->first($teamId);

        $data['team'] = ['name' => $resTeam->name];

        $data['exp_notice'] = "";
        if($resTeam->expire_at < date('Y-m-d H:i:s',strtotime('+3 days'))){
            $systemDep = new SystemDep();
            $resSystem = $systemDep->first();
            $data['exp_notice'] = $resSystem->exp_notice;
        }

        //说明有工会的管理权限，可以看到所有菜单
        if ($resUserHasTeams) {
            $data['keys'] = $resAllPermission;
            $data['is_admin'] = 1;
            return self::response($data);
        }

        //说明是当前工会的会长，可以看到所有菜单
        if ($resTeam->leader_id == $userId) {
            $data['keys'] = $resAllPermission;
            $data['is_admin'] = 1;
            return self::response($data);
        }

        $teamUserDep = new SubTeamUserDep();
        $resTeamUser = $teamUserDep->firstByTeamUser($teamId, $userId);
        if (!$resTeamUser) {
            return self::response([], '无该工会权限', 403);
        }

        $subUserHasRolesDep = new SubUserHasRolesDep();
        $resRole = $subUserHasRolesDep->firstByUserId($teamId,$userId);
        if(!$resRole){
            $data['keys'] = [];
            $data['is_admin'] = 2;
            $data['buttons'] = [];
            return self::response($data);
        }

        $subRoleHasPermissionDep = new SubRoleHasPermissionsDep();
        $resPermissionIds = $subRoleHasPermissionDep->getByRoleId($resRole->role_id);;
        if($resPermissionIds->isEmpty()){
            $data['keys'] = [];
            $data['is_admin'] = 2;
            $data['buttons'] = [];
            return self::response($data);
        }

        $permissionDep = new SubPermissionsDep();
        $resPermissions = $permissionDep->getByIds($resPermissionIds->pluck('permission_id'));
        $resMenu = $resPermissions->filter(function($item){
           return $item->type == 'menu';
        });
        $data['keys'] = $resMenu->map(function($item) use ($permissionDep){
            return $item->guard_name;
        })->values();

        $resButton = $resPermissions->filter(function($item){
            return $item->type == 'button';
        });
        $data['buttons'] = [];
        $resMenu->each(function ($item) use (&$data,$resButton){
            $resButton->each(function($item1) use ($item,&$data) {
                if($item1->parent_id == $item->id){
                    $data['buttons'][$item->guard_name][] = $item1->guard_name;
                }
            });
        });
        $data['is_admin'] = 2;



        return self::response($data);
    }

    public function teamList($request)
    {

        $param = $request->input();
        $userId = $request->user()->id;

        $teamDep = new TeamsDep();
        $teamUserDep = new SubTeamUserDep();
        $gamerDep = new ManagePlayerDep();
        $resList = $teamUserDep->getByUserId($userId);


        $data['list'] = $resList->map(function ($item) use ($teamDep,$gamerDep) {
            $resTeam = $teamDep->first($item->team_id);
            $resCount = $gamerDep->countByTeamId($item->team_id);
            $resOpt = $gamerDep->countOp($item->team_id);
            return [
                'id' => $item->id,
                'team_id' => $item->team_id,
                'team_name' => $resTeam ? $resTeam->name : CommonEnum::DEFAULT_NULL,
                'gamer_count' => $resCount,
                'op_count' => $resOpt,
                'current_map' => $resTeam ? $resTeam->current_map : CommonEnum::DEFAULT_NULL,
                'next_map' => $resTeam ? $resTeam->next_map : CommonEnum::DEFAULT_NULL,
                'next_time' => $resTeam ? $resTeam->next_time : CommonEnum::DEFAULT_NULL,
                'expire_at' => $resTeam ? $resTeam->expire_at : CommonEnum::DEFAULT_NULL,
            ];
        });

        return self::response($data);
    }
}

